package org.jeecg.modules.biz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.util.PasswordUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.base.tappuser.entity.TAppUser;
import org.jeecg.modules.base.tappuser.mapper.TAppUserMapper;
import org.jeecg.modules.base.tappuser.request.BatchUpdatePassword;
import org.jeecg.modules.base.tappuser.service.ITAppUserService;
import org.jeecg.modules.biz.domain.SystemUser;
import org.jeecg.modules.biz.domain.SystemUserRole;
import org.jeecg.modules.biz.mapper.SystemUserMapper;
import org.jeecg.modules.biz.mapper.SystemUserRoleMapper;
import org.jeecg.modules.biz.service.IBizAppUserService;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
@Slf4j
public class BizAppUserServiceImpl implements IBizAppUserService {

    @Autowired
    protected SystemUserMapper systemUserMapper;

    @Autowired
    private TAppUserMapper appUserMapper;

    @Autowired
    private SystemUserRoleMapper systemUserRoleMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void bizSave(TAppUser tAppUser) {
        SystemUser systemUser = linkSystemUser(tAppUser.getAccount(), tAppUser.getPassword());
        tAppUser.setLinkSysUserId(systemUser.getId());
        appUserMapper.insert(tAppUser);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void bizUpdateById(TAppUser tAppUser) {
        TAppUser temp = appUserMapper.selectById(tAppUser.getId());
        String linkSystemUserId = temp.getLinkSysUserId();
        SystemUser systemUser = systemUserMapper.selectById(linkSystemUserId);
        // 只能更新密码
        String passwordEncode = PasswordUtil.encrypt(systemUser.getUsername(),
                tAppUser.getPassword(), systemUser.getSalt());
        systemUser.setPassword(passwordEncode);
        systemUserMapper.updateById(systemUser);
        appUserMapper.updateById(tAppUser);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void bizRemoveById(String id) {
        TAppUser appUser = appUserMapper.selectById(id);
        appUserMapper.deleteById(id);
        systemUserMapper.deleteById(appUser.getLinkSysUserId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void bizRemoveByIds(List<String> list) {
        if (CollectionUtils.isEmpty(list)) return;
        List<TAppUser> appUsers = appUserMapper.selectList(new QueryWrapper<TAppUser>().in("id", list));
        systemUserMapper.deleteBatchIds(appUsers.stream().map(
                TAppUser::getLinkSysUserId).collect(Collectors.toList()));
        appUserMapper.deleteBatchIds(list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response, Class<TAppUser> tAppUserClass) throws Exception {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
            // 获取上传文件对象
            MultipartFile file = entity.getValue();
            ImportParams params = new ImportParams();
            params.setTitleRows(2);
            params.setHeadRows(1);
            params.setNeedSave(true);
            try {
                List<TAppUser> list = ExcelImportUtil.importExcel(file.getInputStream(), tAppUserClass, params);
                //update-begin-author:taoyan date:20190528 for:批量插入数据
                long start = System.currentTimeMillis();
                for (TAppUser appUser : list) {
                    boolean exist = appUserMapper.exists(new QueryWrapper<TAppUser>().eq("account", appUser.getAccount()));
                    if (exist) {
                        throw new Exception("导入的数据中存在已经注册的账号,导入失败!");
                    }
                    SystemUser temp = linkSystemUser(appUser.getAccount(), appUser.getPassword());
                    appUser.setLinkSysUserId(temp.getId());
                    appUserMapper.insert(appUser);
                }
                //400条 saveBatch消耗时间1592毫秒  循环插入消耗时间1947毫秒
                //1200条  saveBatch消耗时间3687毫秒 循环插入消耗时间5212毫秒
                log.info("消耗时间" + (System.currentTimeMillis() - start) + "毫秒");
                //update-end-author:taoyan date:20190528 for:批量插入数据
                return Result.ok("文件导入成功！数据行数：" + list.size());
            } catch (Exception e) {
                //update-begin-author:taoyan date:20211124 for: 导入数据重复增加提示
                String msg = e.getMessage();
                log.error(msg, e);
                throw e;
//                if (msg != null && msg.indexOf("Duplicate entry") >= 0) {
//                    return Result.error("文件导入失败:有重复数据！");
//                } else {
//                    return Result.error("文件导入失败:" + e.getMessage());
//                }
                //update-end-author:taoyan date:20211124 for: 导入数据重复增加提示
            } finally {
                try {
                    file.getInputStream().close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return Result.error("文件导入失败！");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchUpdatePassword(BatchUpdatePassword batchUpdatePassword) {
        String newPassword = batchUpdatePassword.getNewPassword();
        List<String> selectedRowKeys = batchUpdatePassword.getSelectedRowKeys();
        //更新AppUser的密码
        TAppUser updateAppUser = new TAppUser();
        updateAppUser.setPassword(newPassword);
        appUserMapper.update(updateAppUser, new QueryWrapper<TAppUser>().in("id", selectedRowKeys));
        // 更新SystemUser密码
        List<TAppUser> appUsers = appUserMapper.selectBatchIds(selectedRowKeys);
        List<SystemUser> systemUsers = systemUserMapper.selectBatchIds(
                appUsers.stream().map(TAppUser::getLinkSysUserId).collect(Collectors.toList()));
        for (SystemUser systemUser : systemUsers) {
            String passwordEncode = PasswordUtil.encrypt(
                    systemUser.getUsername(), newPassword, systemUser.getSalt());
            systemUser.setPassword(passwordEncode);
            systemUserMapper.updateById(systemUser);
        }
    }

    private SystemUser linkSystemUser(String username, String password) {
        String phone = UUID.randomUUID().toString();
        String email = UUID.randomUUID().toString();
        String realname = UUID.randomUUID().toString();
        SystemUser user = new SystemUser();
        user.setCreateTime(new Date());// 设置创建时间
        String salt = oConvertUtils.randomGen(8);
        String passwordEncode = PasswordUtil.encrypt(username, password, salt);
        user.setSalt(salt);
        user.setUsername(username);
        user.setRealname(realname);
        user.setPassword(passwordEncode);
        user.setEmail(email);
        user.setPhone(phone);
        user.setStatus(CommonConstant.USER_UNFREEZE);
        user.setDelFlag(CommonConstant.DEL_FLAG_0);
        user.setActivitiSync(CommonConstant.ACT_SYNC_1);
        systemUserMapper.insert(user);
        String roles = "ee8626f80f7c2619917b6236f3a7f02b";//默认临时角色 test
        if (oConvertUtils.isNotEmpty(roles)) {
            String[] arr = roles.split(",");
            for (String roleId : arr) {
                SystemUserRole userRole = new SystemUserRole(user.getId(), roleId);
                systemUserRoleMapper.insert(userRole);
            }
        }
        return user;
    }


}
